Skip to content

feat(engine): 建立 Legacy/Rust 引擎边界,并同步 codeguard-skills v0.1.3 - #83

Merged
loong10k merged 8 commits into
mainfrom
chore/skills-v013-and-engine
Sep 28, 2026
Merged

loong10k merged 8 commits into
mainfrom
chore/skills-v013-and-engine

Conversation

@loong10k

Copy link
Copy Markdown
Contributor

背景

codeguard 已拆为独立组件(Rust)。本仓是旧插件,两者现在都能给出检查结论,但此前没有一处声明"谁签发",且退出码语义不同:Legacy 的 3 是参数错误,Rust 的 3 是检查未完成——按同一张表翻译会把"没跑完"读成"通过"。

同时插件 vendor 的 68 个技能仍停在 codeguard-skills@v0.1.2,其文档把用户引向 Rust 侧不存在的命令。

本 PR 两部分

1. 引擎边界(新增)

  • scripts/codeguard/engine.py — 登记两个引擎与权威性,退出码翻译表,未知码 fail closed
  • scripts/engine_report.py + codeguard engine — 只读报告签发方与 Rust 探测结果。Legacy 无 --version(未知子命令退出 1),Rust 以 report_type=version 的 JSON 应答,两者无歧义可分
  • resolve_authoritative(rust_available=True) 仍返回 Legacy:二进制存在不改变权威性
  • 新增 engine 子命令;新模块登记进 SCRIPT_ROLES / CORE_DEPENDENCIES
  • 13 项契约测试

2. vendor 重对齐

lock 由 v0.1.2 / 2c0c807 升至 v0.1.3 / 33d737f,快照与摘要整体刷新。带入源仓的 engine-contract.md 与 5 个技能的命令面修正。

关键约束

Rust 组件当前对所有质量路径固定返回退出码 3,能力矩阵全部 gap——因此它不能签发质量结论。codeguard-check 状态语义新增 INCOMPLETE 以区分"未完成"与"通过"。

这也是本 PR 不剥离 16k 行 Python 内核的原因:现在切换会让已发布插件的所有质量检查恒为未完成。引擎边界让交接变成改一个常量。

验证

  • check_architecture.py → Architecture OK
  • tests/run_all.py → 144 通过 / 0 失败 / 0 跳过
  • validate_portable_plugin.py → PASS(Agent Plugins v1.0.0)
  • skill_vendor.py check → all managed skills match the lockfile
  • unittest discover → 645 项,1 失败 = test_add_all_widens_to_three_lanes(已 stash 验证为预先存在,与本 PR 无关)

loong10k and others added 7 commits September 28, 2026 21:51
补齐 introduce-rust-codeguard-cli 变更的设计文档与规格缺口:

- command-architecture / static-check-catalog / false-positive-allowlist:
  命令面、静态检查目录与已知误报处置
- legacy-delta-20260924 / legacy-v1-protocol-map:遗留实现与 v1 协议映射,
  明确哪些是迁移债、哪些是已完成
- project-initialization:项目初始化能力规格
- architecture / technical-design / coverage-and-acceptance / remediation-workflow
  与各 specs 同步更新,新增 implementation-coverage 汇总覆盖情况

本次提交与 Agent Plugins 可移植布局迁移无关,单独成commit 以便独立回滚。
此前仅发布各客户端专属清单(.codex-plugin/、.zcode-plugin/、kimi.plugin.json),
不符合 Agent Plugins 规范。符合规范的客户端会因缺少根清单而整体拒绝该插件,
其中的 68 个技能一个也加载不到(§5.1/§5.3:缺清单是致命错误,不是警告)。

- 新增根 plugin.json:$schema 常量 + name 约束 + 封闭字段集;客户端专属的
  interface 等数据移入 extensions["com.openai"] / extensions["ai.nanoco.nanoclaw"]
- version 取基础版本,+codex.<stamp> 构建元数据留在兼容通道
- 新增客户端扩展目录,让非可移植的 commands/hooks/agents 对注册表客户端可见:
  - 新增 `com.github.copilot/`(VS Code 与 GitHub Copilot 共用)
  - 新增 `dev.openhands/`(OpenHands)
  根目录副本保留,Codex/ZCode/Kimi 通道不受影响
- 新增 scripts/validate_portable_plugin.py:纯标准库、无网络,按发布 schema
  校验清单、技能发现与镜像漂移
- 新增 docs/portable-migration.md 记录迁移内容与客户端覆盖

校验:19/19 包通过规范校验;4655 个测试,红色套件 9 个且全部为迁移前既有失败,
本次迁移零新增失败。
仓库内同步调整:
- scripts/check_architecture.py:把 scripts/validate_portable_plugin.py 登记进
  SCRIPT_ROLES(角色 entry),否则未分类顶层脚本会触发架构门禁。
插件与独立 Rust 内核各自都能给出检查结论,但此前没有一处声明"谁签发"。
两者的退出码语义也不相同:Legacy 的 3 是参数错误,Rust 的 3 是检查未完成——
按同一张表翻译会把"没跑完"读成"通过"。

- `scripts/codeguard/engine.py`:登记两个引擎与其权威性,提供退出码翻译表。
  未知码一律按 UNVERIFIED 阻塞(fail closed)。
- `scripts/engine_report.py` + `codeguard engine`:只读报告签发方与 Rust 组件
  探测结果。Legacy 无 --version(未知子命令退出 1),Rust 以
  report_type=version 的 JSON 应答,两者可无歧义区分。
- `resolve_authoritative(rust_available=True)` 仍返回 Legacy:二进制存在
  不改变权威性,Rust 在能力矩阵 gap 清空前不能签发质量结论。
- 新增 `engine` 子命令并登记进 SCRIPT_ROLES / CORE_DEPENDENCIES。

13 项契约测试覆盖:两引擎退出码不共享语义、仅 0 可通过、未知码 fail closed、
探测到 Rust 仍不夺权、Legacy 形态不被误判为 Rust。

架构门禁 / run_all 144 / 可移植性校验均绿;unittest discover 645 项中唯一
失败为 test_add_all_widens_to_three_lanes,已 stash 验证为预先存在。
lock 由 v0.1.2 / 2c0c807 升至 v0.1.3 / 33d737f,68 个受管技能快照与摘要整体刷新。

本次同步带入源仓的引擎契约修正:新增 `codeguard/references/operations/engine-contract.md`
作为双引擎命令面的唯一权威对照,并修正 5 个技能与 Rust 内核的调用不一致——
`fix` / `dockerfile` / `--lang` / `--ecosystem` / `--severity` / `--json` 在 Rust 侧不存在。

与本仓新增的 `codeguard engine` 边界报告配套:Rust 组件对所有质量路径固定返回
退出码 3(未完成),不能签发质量结论;`codeguard-check` 的状态语义因此新增
INCOMPLETE,以区分"未完成"与"通过"。

验证:架构门禁 OK / run_all 144 通过 / 可移植性 PASS / skill_vendor check PASS /
unittest discover 645 项中唯一失败为预先存在的 test_add_all_widens_to_three_lanes。
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-28T16:55:09.886690Z 1ea4cc6 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

engine_report.py 有 shebang 但缺执行位;三个 # noqa: E402 在本仓 ruff 配置下
E402 并未启用,属冗余抑制。移除后 `ruff check hooks scripts tests` 全绿。
@loong10k
loong10k merged commit 0ea342f into main Sep 28, 2026
3 checks passed
@loong10k
loong10k deleted the chore/skills-v013-and-engine branch September 28, 2026 16:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ea4cc6f7b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread bin/codeguard
Comment on lines +43 to +44
engine)
exec python3 "$ROOT/scripts/engine_report.py" "$@"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bump the plugin version for the new engine command

This commit adds the user-facing codeguard engine command and refreshes the bundled skills, but all plugin manifests remain at version 0.16.1. Because marketplace update discovery is version-based, existing installations will not be offered this functionality; run the required minor release bump so the catalog and all manifests are regenerated and synchronized.

AGENTS.md reference: AGENTS.md:L13-L14

Useful? React with 👍 / 👎.

Comment thread skills/codeguard/SKILL.md
bin/codeguard cve --severity HIGH
```

Rust 引擎下改用位置参数(`check all|java`、`cve <rust|python|typescript>`),且 `fix`、`--lang`、`--ecosystem`、`--severity` 均不存在。该组件当前对所有质量路径返回退出码 3(未完成),只能表述为局部原生观察,不得据此签发通过。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep Legacy as the gate when Rust is detected

When a Rust binary is present earlier on PATH, this instruction switches the workflow to Rust commands even though the same change declares that Rust always returns INCOMPLETE and that Legacy remains the only authoritative signer. Users in that environment therefore lose the usable bundled gate and can never obtain a PASS/FAIL result; keep bin/codeguard as the quality gate and run Rust only as an optional observation until its authority changes. Since this is a managed skill, correct it in the source skill repository and re-vendor it rather than patching the snapshot directly.

AGENTS.md reference: AGENTS.md:L5-L7

Useful? React with 👍 / 👎.


# Rust:0 通过 / 1 违规 / 2 参数错误 / 3 检查未完成 / 4 内部故障 / 130 用户中断。
RUST_EXIT: dict[int, tuple[Verdict, bool]] = {
0: ("PASS", False),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Block non-authoritative Rust exit-zero outcomes

If a Rust quality invocation returns 0 unexpectedly, translate("rust", 0) produces PASS with blocks=False, even though RUST.authoritative is false and this module states that Rust must not sign any quality conclusion yet. Any gate consumer using the advertised GateOutcome.blocks value would therefore release on a non-authoritative result; apply authority when deriving the gate outcome, or keep Rust exit 0 blocked until the engine is promoted.

Useful? React with 👍 / 👎.

Comment thread scripts/engine_report.py
Legacy CLI 没有 --version(会落入未知子命令并以 1 退出),Rust 组件则以
report_type=version 的 JSON 应答。两者因此可以无歧义区分。
"""
candidate = shutil.which("codeguard")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Continue past the Legacy launcher when probing Rust

When ./bin/codeguard engine is run with the plugin's bin directory before the Rust installation on PATH, shutil.which("codeguard") returns the Legacy launcher itself; its --version failure is treated as final, so the later Rust executable is never examined and the report incorrectly says no Rust component was detected. Skip the current Legacy launcher and continue through matching PATH entries, or accept an explicit Rust executable path.

Useful? React with 👍 / 👎.

LEGACY_EXIT: dict[int, tuple[Verdict, bool]] = {
0: ("PASS", False),
1: ("UNVERIFIED", True),
2: ("FAIL", True),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Distinguish Legacy usage errors from lint failures

For the Legacy check, fix, and dockerfile commands, argparse exits with code 2 on invalid arguments, while this table interprets every Legacy exit 2 as a confirmed quality failure. For example, bin/codeguard check --definitely-invalid returns 2 and would be translated to FAIL rather than UNVERIFIED, corrupting reports that rely on this new boundary; either normalize those CLIs to return 3 for usage errors or make translation command-specific.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant